#ifndef SerialHelper_H
#define SerialHelper_H

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/array.hpp>
#include <boost/asio/steady_timer.hpp>
#include <memory>
#include <thread>
#include <functional>
#include <queue>
#include <string>
#include "def.h"
#include "common.h"

using namespace boost::asio;


const int DATA_BEAT = 2;
const int MAX_BUFFER_LEN = 64;

const char FRAME_HEADER = 0X7B; // Frame_header //帧头
const char FRAME_TAIL = 0X7D;   // Frame_tail   //帧尾

struct MsgBlock
{
    std::vector<u8> vec;

    std::string toString() const
    {
        std::string str;
        for (u8 ch : vec)
        {
            str += toHex(ch);
            str += " ";
        }
        return str;
    }

    bool isValid()
    {
        try
        {
            if (vec[0] == FRAME_HEADER && vec[vec.size() - 1] == FRAME_TAIL)
            {
                int len = vec[1];
                if (checkSum(vec, 2 + len))
                {
                    return true;
                }
            }
        }
        catch (const std::exception &e)
        {
            std::cerr << e.what() << '\n';
        }
        return false;
    }
};

struct SerialConfig
{
    std::string port;
    int baud;
};




class SerialHelper
{
public:
    SerialHelper();
    ~SerialHelper();
   
    void open(const std::string name,SerialConfig config);
    void run();
    void close();
    void writeS(std::string &buf);
    void write(std::vector<u8> &buf);
     typedef std::function<void(MsgBlock)> RecvMsgCallback;
    void setReadCallback(RecvMsgCallback cb) { recv_msg_callback_ = std::move(cb); }
    int get_rec_flag(){return rec_flag;}
    std::vector<u8> get_rec_str() {rec_flag=0;return msg_buf_;}
   void read();
   RecvMsgCallback recv_msg_callback_;
private:
    void startTask();
    void handleStatusInfo(const boost::system::error_code &ec);
    void runThreadFunc();
    

    
    int rec_flag;
private:
    boost::system::error_code ec_;
    io_service io_;
    std::shared_ptr<serial_port> serial_port_;

    char receiveData[MAX_BUFFER_LEN];

    
    std::thread run_thread_;
    std::thread read_thread_;
    // std::thread process_thread_;

    SerialConfig config_;

    boost::asio::steady_timer status_timer_;
    bool is_connected;

    std::string name_;

    std::string recv_msg_;

    std::vector<u8> msg_buf_;
};

#endif // SerialHelper_H